package com.cskaoyan.service;

import com.cskaoyan.bean.bo.*;
import com.cskaoyan.bean.pojo.*;
import com.cskaoyan.bean.vo.wx.CartCheckoutVo;
import com.cskaoyan.bean.vo.wx.CartIndexTotalVo;
import com.cskaoyan.bean.vo.wx.CartIndexVo;
import com.cskaoyan.dao.*;
import com.cskaoyan.exception.CartException;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.System;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @author yfsper233
 * @time 2021/7/10-17:21
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private UserAddressMapper userAddressMapper;
    @Autowired
    private GoodsProductMapper goodsProductMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private CouponUserMapper couponUserMapper;
    @Autowired
    private GrouponRulesMapper grouponRulesMapper;
    @Autowired
    private GrouponMapper grouponMapper;

    private static final long ONE_DAY_MILLISECOND = 86400000;//一天的毫秒数


    @Override
    public CartIndexVo queryCartIndex(Integer id, Integer cartId, Boolean onlyChecked) {
        CartExample cartExample = new CartExample();
        CartExample.Criteria cartExampleCriteria = cartExample.createCriteria();
        cartExampleCriteria.andUserIdEqualTo(id);

        if (cartId == 0) {//购物车点下单的情况，如果是fastadd不经过购物车页面，不必限定未删除
            cartExampleCriteria.andDeletedEqualTo(false);
        }
        if (cartId > 0) {//fastadd的情形
            cartExampleCriteria.andIdEqualTo(cartId);
        }

        if (onlyChecked) {//只选择已选中的
            cartExampleCriteria.andCheckedEqualTo(onlyChecked);
        }

        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        int goodsCount = 0;
        int checkedGoodsCount = 0;
        BigDecimal goodsAmount = new BigDecimal(0);
        BigDecimal checkedGoodsAmount = new BigDecimal(0);
        for (Cart cart : cartList) {
            //true 表示已选中
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cart.getPrice());
            }
            goodsCount += cart.getNumber();
            goodsAmount = goodsAmount.add(cart.getPrice());
        }
        CartIndexTotalVo totalVo = new CartIndexTotalVo(goodsCount, checkedGoodsCount, goodsAmount, checkedGoodsAmount);
        return new CartIndexVo(totalVo, cartList);

    }

    @Override
    public Integer updateCartCheckedStatus(Integer id, CartCheckedBo checkedBo) {
        return null;
    }


    @Override
    public Integer changeCartCheckedStatus(Integer id, CartCheckedBo checkedBo) {
        List<Integer> productIds = checkedBo.getProductIds();
        Integer affectedRows = 0;
        for (Integer productId : productIds) {
            CartExample cartExample = new CartExample();
            CartExample.Criteria cartExampleCriteria = cartExample.createCriteria();
            cartExampleCriteria.andUserIdEqualTo(id).andProductIdEqualTo(productId);
            Cart cart = new Cart();
            cart.setChecked(checkedBo.getIsChecked() != 0);
            cartMapper.updateByExampleSelective(cart, cartExample);
            affectedRows++;
        }
        return affectedRows;
    }

    @Override
    public List<Cart> queryCartById(int id) {
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        criteria.andCheckedEqualTo(true);
        if (id != 0) {
            criteria.andIdEqualTo(id);
        }
        return cartMapper.selectByExample(cartExample);
    }

    @Override
    public CartCheckoutVo queryCartCheckoutInfo(Integer userId, CartCheckoutBo bo, CartIndexVo cartIndexVo) throws CartException {
        //groupRulesId不用管
        //先查地址相关信息
        //如果地址id为0，返回默认id，如果不是0，则查找对应地址
        CartCheckoutVo checkoutVo = new CartCheckoutVo();
        UserAddress userAddress = queryUserAddressByUserId(userId, bo.getAddressId());
        if (userAddress != null) {
            checkoutVo.setCheckedAddress(userAddress);
            checkoutVo.setAddressId(userAddress.getId());
        } else {
            checkoutVo.setCheckedAddress(null);
            checkoutVo.setAddressId(0);
        }

        //购物车商品列表
        List<Cart> cartList = cartIndexVo.getCartList();
        checkoutVo.setCheckedGoodsList(cartList);
        //商品总金额
        BigDecimal goodsTotalPrice = cartIndexVo.getCartTotal().getCheckedGoodsAmount();

        checkoutVo.setGoodsTotalPrice(goodsTotalPrice);

        //根据总金额是否满88决定运费
        int cmp = goodsTotalPrice.compareTo(new BigDecimal(88));
        if (cmp < 0) {
            checkoutVo.setFreightPrice(8);
        } else {
            checkoutVo.setFreightPrice(0);
        }

        //优惠券相关,根据用户id查询其所有优惠券，如果用户自己选择了优惠券，那优惠券id就不是0了
        // 判断可用优惠券的数量，
        // 挑选优惠金额最大的优惠券，作为默认使用的优惠券

        Coupon coupon = null;
        Integer couponId = bo.getCouponId();

        List<Coupon> couponList = queryAvailableCouponList(userId, cartIndexVo, couponId);//获取可用优惠券订单列表
        if (couponId > 0) {
            //用户自己选了优惠券的情况
            coupon = couponMapper.selectByPrimaryKey(couponId);
        } else if (couponId == 0) {
            if (couponList.size() > 0) {
                //可用列表是根据优惠金额从大到小排序的，因此第0个就是优惠值最多的，默认用户会使用这张
                coupon = couponList.get(0);
            }
        }
//        else if (couponId == -1) 不用管 coupon = null

        if (coupon != null && couponList.size() > 0 && couponId != -1) {//选择设置是否显示可用优惠券数量
            checkoutVo.setCouponId(coupon.getId());//有可用优惠券,并且要使用,显示优惠金额
        } else if (coupon == null&&couponList.size() > 0 && couponId == -1) {
            checkoutVo.setCouponId(-1);//有但选择不使用
        } else {
            checkoutVo.setCouponId(0);//没有可用默认显示0
        }

        checkoutVo.setAvailableCouponLength(couponList.size());

        if (coupon != null) {
            checkoutVo.setCouponPrice(coupon.getDiscount());
        }//否则就是没有合适的优惠券，用默认值0；也可能是用户选择不适用优惠券，所以还要设置可用setAvailableCouponLength
        else {
            checkoutVo.setCouponPrice(new BigDecimal(0));
        }

        //团购优惠
        BigDecimal groupDiscount = queryGroupDiscount(userId, bo.getGrouponRulesId(), cartIndexVo);
        //加上运费，减去优惠券优惠,减去团购优惠
        BigDecimal orderTotalPrice = goodsTotalPrice.add(new BigDecimal(checkoutVo.getFreightPrice())).subtract(checkoutVo.getCouponPrice()).subtract(groupDiscount);
        checkoutVo.setActualPrice(orderTotalPrice);
        checkoutVo.setOrderTotalPrice(orderTotalPrice);
        checkoutVo.setGrouponPrice(groupDiscount);

        return checkoutVo;
    }

    @Override
    public Integer queryCartGoodsCount(Integer userId) {
        CartExample cartExample = new CartExample();
        CartExample.Criteria cartExampleCriteria = cartExample.createCriteria();
        cartExampleCriteria.andUserIdEqualTo(userId)
                .andDeletedEqualTo(false);
        List<Cart> cartList = cartMapper.selectByExample(cartExample);
        Integer count = 0;
        for (Cart cart : cartList) {
            count += cart.getNumber();
        }
        return count;
    }

    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer addCart(CartAddBo cartAddBo, Integer userId, Boolean isFastAdd) {
        Cart cart = new Cart();
        List<Cart> cartList = null;
        //先去查product表
        GoodsProduct goodsProduct = goodsProductMapper.selectByPrimaryKey(cartAddBo.getProductId());
        if (goodsProduct == null || goodsProduct.getNumber() < cartAddBo.getNumber()) {
            throw new CartException("商品库存不足");
        }
        //减库存
        goodsProduct.setNumber(goodsProduct.getNumber() - cartAddBo.getNumber());
        goodsProductMapper.updateByPrimaryKey(goodsProduct);
        if (!isFastAdd) {
            //根据用户id，商品id，货品id去查购物车中是否已有该条记录(如果是fastadd则不用)
            CartExample cartExample = new CartExample();
            CartExample.Criteria cartExampleCriteria = cartExample.createCriteria();
            cartExampleCriteria.andDeletedEqualTo(false)
                    .andUserIdEqualTo(userId)
                    .andGoodsIdEqualTo(cartAddBo.getGoodsId())
                    .andProductIdEqualTo(cartAddBo.getProductId());
            cartList = cartMapper.selectByExample(cartExample);
        }

        if (cartList != null && cartList.size() > 0) {
            cart = cartList.get(0);
            cart.setPrice(goodsProduct.getPrice().multiply(new BigDecimal(cartAddBo.getNumber())).add(cart.getPrice()));
            cart.setNumber((short) (cartAddBo.getNumber() + cart.getNumber()));
            cart.setUpdateTime(new Date(System.currentTimeMillis()));
            cartMapper.updateByPrimaryKeySelective(cart);
        } else {
            //计算货品总金额
            cart.setPrice(goodsProduct.getPrice().multiply(new BigDecimal(cartAddBo.getNumber())));
            cart.setNumber((short) cartAddBo.getNumber());
            cart.setProductId(goodsProduct.getId());
            cart.setSpecifications(goodsProduct.getSpecifications());
            cart.setAddTime(new Date(System.currentTimeMillis()));
            cart.setUpdateTime(new Date(System.currentTimeMillis()));

            //再去查goods表
            Goods goods = goodsMapper.selectByPrimaryKey(cartAddBo.getGoodsId());
            if (goods == null) {
                throw new CartException("商品库存不足");
            }
            cart.setGoodsId(goods.getId());
            cart.setGoodsSn(goods.getGoodsSn());
            cart.setGoodsName(goods.getName());
            cart.setPicUrl(goods.getPicUrl());
            cart.setDeleted(false);
            cart.setUserId(userId);

            cartMapper.insertSelective(cart);
        }


        return cart.getId();
    }

    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer changeCartProductNum(CartUpdateBo cartUpdateBo) {
        //查询product表
        GoodsProduct goodsProduct = goodsProductMapper.selectByPrimaryKey(cartUpdateBo.getProductId());

        //更新product货品表中的库存
        if (cartUpdateBo.getNumber() > goodsProduct.getNumber()) {
            throw new CartException("库存不足");
        }
        goodsProduct.setNumber(goodsProduct.getNumber() - cartUpdateBo.getNumber());
        int affectedRows = goodsProductMapper.updateByPrimaryKeySelective(goodsProduct);

        //更新cart购物车表中的库存和总价
        Cart cart = new Cart();
        cart.setNumber((short) cartUpdateBo.getNumber());
        cart.setId(cartUpdateBo.getId());
        BigDecimal totalPrice = goodsProduct.getPrice().multiply(new BigDecimal(cart.getNumber()));
        cart.setPrice(totalPrice);
        cart.setUpdateTime(new Date(System.currentTimeMillis()));
        int affectedRows2 = cartMapper.updateByPrimaryKeySelective(cart);
        if (affectedRows == 1 && affectedRows2 == 1) {
            return 200;
        }
        return 400;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer removeCartByUserIdAndProductIds(List<Integer> deleteList, Integer userId) {
        Integer affectedRows = 0;
        for (Integer productId : deleteList) {

            //查找cart表，得到数量信息
            CartExample cartExample = new CartExample();
            CartExample.Criteria cartExampleCriteria = cartExample.createCriteria();
            cartExampleCriteria.andProductIdEqualTo(productId)
                    .andUserIdEqualTo(userId)
                    .andDeletedEqualTo(false);
            List<Cart> carts = cartMapper.selectByExample(cartExample);
            if (carts.size() != 0) {
                Short number = carts.get(0).getNumber();
                //逻辑删除该条记录
                Cart cart = new Cart();
                cart.setDeleted(true);
                cart.setId(carts.get(0).getId());
                cartMapper.updateByPrimaryKeySelective(cart);

                //查找goodsProduct表，得到number
                GoodsProduct goodsProduct = goodsProductMapper.selectByPrimaryKey(productId);
                //更新查找goodsProduct表的number信息
                goodsProduct.setNumber(goodsProduct.getNumber() + number);
                int updateRow = goodsProductMapper.updateByPrimaryKeySelective(goodsProduct);

                affectedRows += updateRow;
            }

        }

        return affectedRows;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer removeCartByCartId(Integer result) {
        Cart cart = new Cart();
        cart.setId(result);
        cart.setDeleted(true);
        int affectedRows = cartMapper.updateByPrimaryKeySelective(cart);

        return affectedRows;
    }

    @SneakyThrows
    @Override
    public UserAddress queryUserAddressByUserId(Integer userId, Integer addressId) {

        UserAddressExample userAddressExample = new UserAddressExample();
        UserAddressExample.Criteria addressExampleCriteria = userAddressExample.createCriteria();
        userAddressExample.setOrderByClause("is_default" + " " + "desc");
        addressExampleCriteria.andUserIdEqualTo(userId)
                .andDeletedEqualTo(false);
        if (addressId != 0) {
            addressExampleCriteria.andIdEqualTo(addressId);
        }

        List<UserAddress> userAddressList = userAddressMapper.selectByExample(userAddressExample);
        if (userAddressList != null && userAddressList.size() > 0) {
            return userAddressList.get(0);
        }
        return null;
    }

    @Override
    public List<Coupon> queryAvailableCouponList(Integer userId, CartIndexVo cartInfo, Integer couponId) {
        List<Cart> cartList = cartInfo.getCartList();
        List<Coupon> couponList = new ArrayList<>();

        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        Date nowTime = new Date(System.currentTimeMillis());
        criteria.andDeletedEqualTo(false)
                .andStatusEqualTo((short) 0)
                .andUserIdEqualTo(userId)
                .andStartTimeLessThanOrEqualTo(nowTime)
                .andEndTimeGreaterThan(nowTime);
        couponUserExample.setOrderByClause("add_time" + " " + "desc");
        List<CouponUser> couponUserList = couponUserMapper.selectByExample(couponUserExample);
        ArrayList<Integer> couponIds = new ArrayList<>();
        for (CouponUser couponUser : couponUserList) {
            couponIds.add(couponUser.getCouponId());
        }
//        for (int i = couponUserList.size() - 1; i >= 0; i--) {
////            if (couponUserList.get(i).getStartTime().getTime() > nowTime.getTime() || couponUserList.get(i).getEndTime().getTime() < nowTime.getTime()) {
////                couponUserList.remove(couponUserList.get(i));
////                continue;
////            }
//            couponIds.add(couponUserList.get(i).getCouponId());
//        }

        CouponExample couponExample = new CouponExample();
        couponExample.setOrderByClause("discount" + " " + "desc");
        CouponExample.Criteria couponExampleCriteria = couponExample.createCriteria();
        couponExampleCriteria
                .andMinLessThanOrEqualTo(cartInfo.getCartTotal().getCheckedGoodsAmount())
                .andDeletedEqualTo(false)
                .andStatusEqualTo((short) 0);
        if (couponIds.size() > 0) {
            couponExampleCriteria.andIdIn(couponIds);

            couponList = couponMapper.selectByExample(couponExample);
        } else {
            return couponList;
        }
        //到此还有goods_type和time_type限制没有检测
        ArrayList<Integer> unavailableIds = new ArrayList<>();
        ArrayList<Integer> unavailableIds2 = new ArrayList<>();
        for (Coupon cpn : couponList) {
//            //有效时间限制
//            if (cpn.getTimeType() == 0) {
//                //如果是0，则基于领取时间的有效天数days
//                //要先获取用户领取优惠券的时间
//                Date createTime = null;
//                for (CouponUser couponUser : couponUserList) {
//                    if (couponUser.getCouponId() == cpn.getId() && couponUser.getUserId() == userId) {
//                        //找到了该用户领的的这张优惠券
//                        createTime = couponUser.getAddTime();
//                        //考虑到用户的这种优惠券可能不止一张，将这张排除以免影响下次循环
//                        unavailableIds.add(couponUserList.indexOf(couponUser));
//                        break;
//                    }
//                }
//                for (Integer unavailableId : unavailableIds) {
//                    couponUserList.remove(unavailableId);
//                }
//
//                if (createTime == null || createTime.getTime() + cpn.getDays() * ONE_DAY_MILLISECOND < System.currentTimeMillis()) {
//                    //过期了
//                    unavailableIds2.add(couponList.indexOf(cpn));//将优惠券从可用优惠券列表中删除
//                    continue;//继续判断下一条优惠券
//                }
//            } else {
//                //如果是1，则start_time和end_time是优惠券有效期
//                Date now = new Date(System.currentTimeMillis());
//                if (now.compareTo(cpn.getStartTime()) < 0 || now.compareTo(cpn.getEndTime()) >= 0) {
//                    unavailableIds2.add(couponList.indexOf(cpn));//将优惠券从可用优惠券列表中删除
//                    continue;//继续判断下一条优惠券
//                }
//            }
            //商品类型限制
            if (cpn.getGoodsType() == 1) {
                //类目集合限制
                ArrayList<Integer> categorySetLimit = new ArrayList<>();
                //根据goodsId查找categoryid
                for (Cart cart : cartList) {
                    Goods goods = goodsMapper.selectByPrimaryKey(cart.getGoodsId());
                    categorySetLimit.add(goods.getCategoryId());
                }
                if (!Arrays.asList(cpn.getGoodsValue()).containsAll(categorySetLimit)) {
                    //当前订单类目超出了优惠券限制类目限制集合
                    unavailableIds2.add(couponList.indexOf(cpn));//将优惠券从可用优惠券列表中删除
                    continue;//继续判断下一条优惠券
                }
            } else if (cpn.getGoodsType() == 2) {
                //商品集合限制
                ArrayList<Integer> goodsSetLimit = new ArrayList<>();
                for (Cart cart : cartList) {
                    goodsSetLimit.add(cart.getGoodsId());
                }
                if (!Arrays.asList(cpn.getGoodsValue()).containsAll(goodsSetLimit)) {
                    //当前订单商品集合超出了限制
                    unavailableIds2.add(couponList.indexOf(cpn));
                    continue;
                }
            }
        }
        for (Integer integer : unavailableIds2) {//删除不和要求的
            couponList.remove(integer);
        }
        return couponList;
    }

    @Override
    public BigDecimal queryGroupDiscount(Integer userId, Integer groupRulesId, CartIndexVo cartInfo) {

        BigDecimal groupDiscount = new BigDecimal(0);
        List<Cart> cartList = cartInfo.getCartList();
        if (groupRulesId > 0) {//团购id<=0表示没有参与团购优惠
            //根据团购规则id查询该团购规则当前是否过期，以及团购规则要求的优惠人数
            GrouponRules grouponRules = grouponRulesMapper.selectByPrimaryKey(groupRulesId);
            if (grouponRules != null
                    && grouponRules.getExpireTime().getTime() > System.currentTimeMillis()//过期校验
                    && cartList.size() == 1  //团购优惠商品校验，要求订单单中有且只有该团购规则中的商品
                    && grouponRules.getGoodsId().equals(cartList.get(0).getGoodsId())) {//团购优惠商品校验，要求订单中有且只有该团购规则中的商品
                //根据用户id和团购规则id，查找其所在的团购的团id，再查询当前团内有多少人
//                GrouponExample grouponExample = new GrouponExample();
//                GrouponExample.Criteria criteria = grouponExample.createCriteria();
//                criteria.andUserIdEqualTo(userId).andRulesIdEqualTo(groupRulesId).andDeletedEqualTo(false);
//
//                List<Groupon> groupons = grouponMapper.selectByExample(grouponExample);
//                if (groupons != null && groupons.size() > 0) {
//                    Integer groupId = groupons.get(0).getGrouponId();//拿到团购信息中的团id
//                    //根据团id查询团内现有多少人
//                    int count = grouponMapper.selectJoinerCountByGrouponId(groupId);
//                    if (count >= grouponRules.getDiscountMember()) {
                groupDiscount = grouponRules.getDiscount();
//                    }
//                }
            }
        }
        return groupDiscount;
    }

    @Override
    public int removeCartByIdList(ArrayList<Integer> idList) {
        CartExample cartExample = new CartExample();
        cartExample.createCriteria().andIdIn(idList);
        Cart cart = new Cart();
        cart.setDeleted(true);

        return cartMapper.updateByExampleSelective(cart, cartExample);

    }
}
